still some bugs and auth issues to iron out. need to implement a new action button/bar, the card for moments in a space, creating new moments and essays, dynamically refreshing the spaces view when a new post is created.

This commit is contained in:
2025-05-20 19:46:09 -06:00
parent a93c30c40f
commit 54a01f0f1f
20 changed files with 1018 additions and 1191 deletions
+118
View File
@@ -0,0 +1,118 @@
let actionButton = document.querySelector("#actionButton");
let newPostButton = document.querySelector("#newPost");
let newSpaceButton = document.querySelector("#newSpace");
let filterSortButton = document.querySelector("#filterSort");
let circle = document.querySelector(".circleLayout");
let modal = document.querySelector("#stdModal");
let state = "hide";
actionButton.addEventListener("click", () => {
if (state == "hide") {
state = "show";
newPostButton.style.display = "flex";
newSpaceButton.style.display = "flex";
filterSortButton.style.display = "flex";
circle.style.backgroundColor = "#FFFFFF";
newPostButton.addEventListener("click", () => {
fetch("director.php", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: "ajaxId=newPostHTML",
})
.then((response) => {
return response.json();
})
.then((data) => {
modal.innerHTML = data["html"];
modal.style.display = "flex";
let newNavThought = document.querySelector("#newNavThought");
let newThought = document.querySelector("#newThought");
let newNavMoment = document.querySelector("#newNavMoment");
let newMoment = document.querySelector("#newMoment");
let newNavEssay = document.querySelector("#newNavEssay");
let newEssay = document.querySelector("#newEssay");
let newPostLabel = document.querySelector("#newPostLabel");
let postType = document.querySelector("#postType");
let share = document.querySelector("#share");
share.addEventListener("click", (e) => {
e.preventDefault();
switch (postType.value) {
case "Thought":
let thought = document.querySelector("#thought");
// TODO: Retrieve space dynamically.
fetch("director.php", {
method: "POST",
// TODO: Add Authorization header with JWT
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body:
"ajaxId=newThought&space=1&thought=" +
encodeURIComponent(thought.value),
}).then((response) => {
console.log(response.json());
modal.style.display = "none";
});
break;
case "Moment":
break;
case "Essay":
break;
}
});
newNavThought.addEventListener("click", () => {
newMoment.style.display = "none";
newEssay.style.display = "none";
newThought.style.display = "flex";
newPostLabel.innerText = "New Thought";
newThought.querySelector('input[type="text"]').focus();
postType.value = "Thought";
});
newNavMoment.addEventListener("click", () => {
newThought.style.display = "none";
newEssay.style.display = "none";
newMoment.style.display = "flex";
newPostLabel.innerText = "New Moment";
newMoment.querySelector('input[type="text"]').focus();
postType.value = "Moment";
});
newNavEssay.addEventListener("click", () => {
newThought.style.display = "none";
newMoment.style.display = "none";
newEssay.style.display = "flex";
newPostLabel.innerText = "New Essay";
newEssay.querySelector('input[type="text"]').focus();
postType.value = "Essay";
});
return data;
});
});
newSpaceButton.addEventListener("click", () => { });
filterSortButton.addEventListener("click", () => { });
} else if (state == "show") {
state = "hide";
newPostButton.style.display = "none";
newSpaceButton.style.display = "none";
filterSortButton.style.display = "none";
circle.style.backgroundColor = "transparent";
}
});
+84 -63
View File
@@ -1,72 +1,93 @@
const form = document.querySelector('#login_form');
const username_field = form.querySelector('#username');
const password_field = form.querySelector('#password');
const password_hash_field = form.querySelector('#password_hash');
const submit_button = form.querySelector('input[type="submit"]');
const login = document.querySelector("#login");
const logout = document.querySelector("#logout");
const stdModal = document.querySelector("#stdModal");
submit_button.addEventListener('click', async (e) => {
e.preventDefault();
const password_hash = await hashString(password_field.value);
const urlParams = new URLSearchParams(document.location.search);
const redirect = decodeURI(urlParams.get('redirect'));
requestAuth(username_field.value, password_hash, redirect);
});
function requestAuth(username, password_hash, redirect) {
fetch('http://localhost:7477/auth', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: 'username=' + username + '&password_hash=' + password_hash,
})
.then(response => {
if (!response.ok) {
console.log('Login Failed!');
}
return response.json(); // Parse response body as JSON
})
.then(data => {
notifyServer(data["id"], username, 1, redirect);
});
}
function notifyServer(id, username, role, redirect) {
fetch('director.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: 'ajax_id=login&user_id=' + id + '&username=' + username + '&role=' + role,
})
.then(response => {
return response.json();
})
.then(data => {
if ('startViewTransition' in document) {
if (logout) {
logout.addEventListener("click", () => {
fetch("director.php", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: "ajaxId=logout",
}).then(() => {
if ("startViewTransition" in document) {
document.startViewTransition(() => {
if (redirect == null) {
window.location.href = 'articles.php?view=list&sort=new';
} else {
window.location.href = redirect;
}
window.location.href = "spaces.php?view=list";
});
} else {
// Fallback for browsers that don't support View Transitions
if (redirect == null) {
window.location.href = 'articles.php?view=list&sort=new';
} else {
window.location.href = redirect;
}
window.location.href = "spaces.php?view=list";
}
});
});
}
async function hashString(str) {
const encoded = new TextEncoder().encode(str);
const digest = await crypto.subtle.digest('SHA-256', encoded);
const hashArray = Array.from(new Uint8Array(digest));
const hashHex = hashArray.map(byte => byte.toString(16).padStart(2, '0')).join('');
return hashHex;
if (login) {
login.addEventListener("click", () => {
console.log("click");
stdModal.innerHTML = `
<div class="form_card">
<h3 class="underline">Log In</h3>
<form method="post" id="login_form" action="director.php">
<input type="hidden" name="form_id" value="login_form">
<input type="hidden" name="password_hash" value="" id="password_hash">
<label for="username">Username / Email</label>
<input id="username" name="username" spellcheck="false" required autofocus>
<label for="password">Password</label>
<input id="password" name="password" type="password" spellcheck="false" required>
<label class="form_checkbox_container">Stay Logged In?
<input name="stay_logged_in" type="checkbox" value="true">
<span class="checkmark"></span>
</label>
<input class="button" type="submit" value="Log In">
</form>
<script src="js/login.js" defer></script>
</div>
`;
stdModal.style.display = "flex";
const form = document.querySelector("#login_form");
const username_field = form.querySelector("#username");
const passwordField = form.querySelector("#password");
const submit_button = form.querySelector('input[type="submit"]');
submit_button.addEventListener("click", async (e) => {
e.preventDefault();
requestAuth(username_field.value, passwordField.value);
});
function requestAuth(username, password) {
fetch("director.php", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: "ajaxId=login&username=" + username + "&password=" + password,
})
.then((response) => {
if (!response.ok) {
console.log("Login Failed!");
}
return response.json();
})
.then((data) => {
console.log(data);
if ("startViewTransition" in document) {
document.startViewTransition(() => {
window.location.href = data["redirect"];
});
} else {
// Fallback for browsers that don't support View Transitions
window.location.href = data["redirect"];
}
});
}
});
}