Add JS front-end handling for most forms

This commit is contained in:
Florine W. Dekker 2022-08-12 16:18:15 +02:00
parent f6b93f6809
commit 9d3cf92a9d
Signed by: FWDekker
GPG Key ID: D3DCFAA8A4560BE0
3 changed files with 293 additions and 113 deletions

View File

@ -35,6 +35,11 @@ if (!file_exists($config["database"]["filename"])) {
// Start session
session_start();
// Read JSON from POST, if it's there
if (empty($_POST)) {
$_POST = json_decode(file_get_contents("php://input"), associative: true);
}
if (isset($_POST["action"])) {
// Process POST
switch ($_POST["action"]) {
@ -261,18 +266,29 @@ if (isset($_POST["action"])) {
}
} else if (isset($_GET["action"])) {
// Process GET
if ($_GET["action"] === "list-trackings") {
if (!isset($_SESSION["uuid"])) {
exit("\"not logged in\"");
}
switch ($_GET["action"]) {
case "get-user-data":
if (!isset($_SESSION["uuid"])) {
exit("\"not logged in\"");
}
$db = new Database($config["database"]["filename"], SQLITE3_OPEN_READONLY);
$trackings = $db->list_trackings($_SESSION["uuid"], $_SESSION["uuid"]);
$db->close();
$db = new Database($config["database"]["filename"], SQLITE3_OPEN_READONLY);
$user_data = $db->get_user_by_uuid($_SESSION["uuid"]);
$db->close();
exit(json_encode($trackings));
} else if ($_GET["action"] === "is-alive") {
exit(json_encode((new MyMediawiki())->people_are_alive(array("Janelle Monáe", "John Malkovich", "Adolf Hitler"))));
exit(json_encode($user_data));
case "list-trackings":
if (!isset($_SESSION["uuid"])) {
exit("\"not logged in\"");
}
$db = new Database($config["database"]["filename"], SQLITE3_OPEN_READONLY);
$trackings = $db->list_trackings($_SESSION["uuid"]);
$db->close();
exit(json_encode($trackings));
case "is-alive":
exit(json_encode((new MyMediawiki())->people_are_alive(array("Janelle Monáe", "John Malkovich", "Adolf Hitler"))));
}
}

View File

@ -39,107 +39,128 @@ $_SESSION["token"] = bin2hex(random_bytes(32));
<div id="header"></div>
<section class="container">
<h1>Register</h1>
<form action="api.php" method="post">
<input type="hidden" name="action" value="register" />
<input type="hidden" name="token" value="<?= $_SESSION["token"] ?>" />
<label>
Email
<input type="email" name="email" />
</label>
<label>
Password
<input type="password" name="password" />
</label>
<label>
Confirm password
<input type="password" name="password_confirm" />
</label>
<div class="row hidden" id="loginRow">
<div class="column">
<h2>Log in</h2>
<p>Already have an account? Welcome back!</p>
<form id="loginForm" onsubmit="return false;">
<p class="error"></p>
<input type="hidden" name="token" value="<?= $_SESSION["token"] ?>" />
<label>
Email
<input type="email" name="email" />
</label>
<label>
Password
<input type="password" name="password" />
</label>
<button>Log in</button>
</form>
</div>
<div class="column">
<h2>Register</h2>
<p>
New user?
Create an account!
You can always delete your account and associated data.
Check the <a href="https://fwdekker.com/privacy/">privacy policy</a> for more information.
</p>
<form id="registerForm" onsubmit="return false;">
<p class="error"></p>
<input type="hidden" name="token" value="<?= $_SESSION["token"] ?>" />
<label>
Email
<input type="email" name="email" />
</label>
<label>
Password
<input type="password" name="password" />
</label>
<label>
Confirm password
<input type="password" name="password_confirm" />
</label>
<button>Create account</button>
</form>
</div>
</div>
<input type="submit" />
</form>
<div class="row hidden" id="trackingRow">
<div class="column">
<h2>Trackings</h2>
<pre id="trackings"></pre>
</div>
<div class="column">
<h3>Add tracking</h3>
<form id="addTrackingForm" onsubmit="return false;">
<p class="error"></p>
<input type="hidden" name="token" value="<?= $_SESSION["token"] ?>" />
<label>
Person name
<input name="person_name" />
</label>
<button>Add tracking</button>
</form>
</div>
<div class="column">
<h3>Delete tracking</h3>
<form id="deleteTrackingForm" onsubmit="return false;">
<p class="error"></p>
<input type="hidden" name="token" value="<?= $_SESSION["token"] ?>" />
<label>
Person name
<input name="person_name" />
</label>
<button>Delete tracking</button>
</form>
</div>
</div>
<h1>Log in</h1>
<form action="api.php" method="post">
<input type="hidden" name="action" value="login" />
<input type="hidden" name="token" value="<?= $_SESSION["token"] ?>" />
<label>
Email
<input type="email" name="email" />
</label>
<label>
Password
<input type="password" name="password" />
</label>
<input type="submit" />
</form>
<h1>Log out</h1>
<form action="api.php" method="post">
<input type="hidden" name="action" value="logout" />
<input type="hidden" name="token" value="<?= $_SESSION["token"] ?>" />
<input type="submit" />
</form>
<h1>Login status</h1>
<?= isset($_SESSION["uuid"]) ? "logged in" : "not logged in"; ?>
<h1>Change email</h1>
<form action="api.php" method="post">
<input type="hidden" name="action" value="user-update-email" />
<input type="hidden" name="token" value="<?= $_SESSION["token"] ?>" />
<label>
Email
<input type="email" name="email" />
</label>
<input type="submit" />
</form>
<h1>Change password</h1>
<form action="api.php" method="post">
<input type="hidden" name="action" value="user-update-password" />
<input type="hidden" name="token" value="<?= $_SESSION["token"] ?>" />
<label>
Old password
<input type="password" name="password_old" />
</label>
<label>
New password
<input type="password" name="password_new" />
</label>
<label>
Confirm new password
<input type="password" name="password_confirm" />
</label>
<input type="submit" />
</form>
<h1>Add tracking</h1>
<form action="api.php" method="post">
<input type="hidden" name="action" value="add-tracking" />
<input type="hidden" name="token" value="<?= $_SESSION["token"] ?>" />
<label>
Person name
<input name="person_name" />
</label>
<input type="submit" />
</form>
<h1>Remove tracking</h1>
<form action="api.php" method="post">
<input type="hidden" name="action" value="delete-tracking" />
<input type="hidden" name="token" value="<?= $_SESSION["token"] ?>" />
<label>
Person name
<input name="person_name" />
</label>
<input type="submit" />
</form>
<h1>Trackings</h1>
<pre id="trackings">
</pre>
<div class="row hidden" id="accountRow">
<div class="column">
<h2>Manage account</h2>
<form id="logoutForm" onsubmit="return false;">
<p class="error"></p>
<input type="hidden" name="token" value="<?= $_SESSION["token"] ?>" />
<button>Log out</button>
</form>
</div>
<div class="column">
<h3>Change email</h3>
Current email: TODO<br />
Verified? TODO
<form action="api.php" method="post">
<input type="hidden" name="action" value="user-update-email" />
<input type="hidden" name="token" value="<?= $_SESSION["token"] ?>" />
<label>
Email
<input type="email" name="email" />
</label>
<input type="submit" value="Change email" />
</form>
</div>
<div class="column">
<h3>Change password</h3>
Last changed: TODO
<form action="api.php" method="post">
<input type="hidden" name="action" value="user-update-password" />
<input type="hidden" name="token" value="<?= $_SESSION["token"] ?>" />
<label>
Old password
<input type="password" name="password_old" />
</label>
<label>
New password
<input type="password" name="password_new" />
</label>
<label>
Confirm new password
<input type="password" name="password_confirm" />
</label>
<input type="submit" value="Change password" />
</form>
</div>
</div>
</section>
</div>
<div id="footer"></div>

View File

@ -2,7 +2,14 @@
const {$, doAfterLoad, footer, header, nav} = window.fwdekker;
doAfterLoad(() => {
function refreshTrackings() {
fetch("api.php?action=list-trackings")
.then(it => it.text())
.then(it => $("#trackings").innerText = it);
}
doAfterLoad(async () => {
// Initialize template
$("#nav").appendChild(nav("/Tools/Death-Notifier/"));
$("#header").appendChild(header({
@ -15,7 +22,143 @@ doAfterLoad(() => {
}));
$("main").classList.remove("hidden");
fetch("api.php?action=list-trackings")
.then(it => it.text())
.then(it => $("#trackings").innerText = it);
// Workflow
const loginRow = $("#loginRow");
const trackingRow = $("#trackingRow");
const accountRow = $("#accountRow");
// TODO: Move common code to a Form class or sth... (or actually, wait with that until I have the table thingy
// implemented!)
$("#loginForm").addEventListener("submit", async () => {
$("#loginForm .error").innerText = "";
const response = await fetch("api.php", {
method: "post",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({
action: "login",
// TODO: Deal with tokens in a smarter way. Allow refreshing them! Also remove duplication...
token: $("#loginForm input[name=token]").value,
email: $("#loginForm input[name=email]").value,
password: $("#loginForm input[name=password]").value,
})
}).then(it => it.json());
if (response !== true) {
$("#loginForm .error").innerText = response;
return;
}
$("#loginForm").reset();
loginRow.classList.add("hidden");
trackingRow.classList.remove("hidden");
accountRow.classList.remove("hidden");
refreshTrackings();
});
$("#registerForm").addEventListener("submit", async () => {
$("#registerForm .error").innerText = "";
const response = await fetch("api.php", {
method: "post",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({
action: "register",
token: $("#registerForm input[name=token]").value,
email: $("#registerForm input[name=email]").value,
password: $("#registerForm input[name=password]").value,
password_confirm: $("#registerForm input[name=password_confirm]").value,
})
}).then(it => it.json());
if (response !== true) {
$("#registerForm .error").innerText = response;
return;
}
$("#registerForm").reset();
$("#registerForm .error").innerText = "Account created successfully! You may now log in.";
});
$("#addTrackingForm").addEventListener("submit", async () => {
$("#addTrackingForm .error").innerText = "";
const response = await fetch("api.php", {
method: "post",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({
action: "add-tracking",
token: $("#addTrackingForm input[name=token]").value,
person_name: $("#addTrackingForm input[name=person_name]").value,
})
}).then(it => it.json());
if (response !== true) {
$("#addTrackingForm .error").innerText = response;
return;
}
$("#addTrackingForm").reset();
refreshTrackings();
});
$("#deleteTrackingForm").addEventListener("submit", async () => {
$("#deleteTrackingForm .error").innerText = "";
const response = await fetch("api.php", {
method: "post",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({
action: "delete-tracking",
token: $("#deleteTrackingForm input[name=token]").value,
person_name: $("#deleteTrackingForm input[name=person_name]").value,
})
}).then(it => it.json());
if (response !== true) {
$("#deleteTrackingForm .error").innerText = response;
return;
}
$("#deleteTrackingForm").reset();
refreshTrackings();
});
$("#logoutForm").addEventListener("submit", async () => {
$("#logoutForm .error").innerText = "";
const response = await fetch("api.php", {
method: "post",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({
action: "logout",
token: $("#logoutForm input[name=token]").value,
})
}).then(it => it.json());
if (response !== true) {
$("#logoutForm .error").innerText = response;
return;
}
$("#logoutForm").reset();
loginRow.classList.remove("hidden");
trackingRow.classList.add("hidden");
accountRow.classList.add("hidden");
});
const userData = await fetch("api.php?action=get-user-data").then(it => it.text());
if (userData === "\"not logged in\"") {
loginRow.classList.remove("hidden");
} else {
trackingRow.classList.remove("hidden");
accountRow.classList.remove("hidden");
refreshTrackings();
}
});