implemented spaces, fixed login and signup, thought creation and space creation.

This commit is contained in:
2025-05-26 13:00:12 -06:00
parent 54a01f0f1f
commit d3fa1733f4
32 changed files with 1499 additions and 1132 deletions
+104
View File
@@ -0,0 +1,104 @@
const bar = document.querySelector("#actionBar");
const actionSpace = bar.querySelector("#actionSpace");
const actionPost = bar.querySelector("#actionPost");
actionSpace.addEventListener("click", () => {
document.querySelector("#primaryActions").style.display = "none";
document.querySelector("#spaceActions").style.display = "flex";
document.querySelector("#spaceBack").addEventListener("click", () => {
document.querySelector("#primaryActions").style.display = "flex";
document.querySelector("#spaceActions").style.display = "none";
});
let home = document.querySelector("#spaceHome");
home.addEventListener("click", () => {
applyTransition(home.getAttribute("href"));
});
document.querySelector("#spaceNew").addEventListener("click", () => {
fetch("director.php", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: "ajaxId=newSpaceHTML",
})
.then((response) => {
return response.json();
})
.then((data) => {
openModal(data["html"]);
document.querySelector("#redirect").value = window.location.href;
});
});
});
actionPost.addEventListener("click", () => {
document.querySelector("#primaryActions").style.display = "none";
document.querySelector("#postActions").style.display = "flex";
document.querySelector("#postBack").addEventListener("click", () => {
document.querySelector("#primaryActions").style.display = "flex";
document.querySelector("#postActions").style.display = "none";
});
document.querySelector("#postNew").addEventListener("click", (e) => {
fetch("director.php", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: "ajaxId=newPostHTML",
})
.then((response) => {
return response.json();
})
.then((data) => {
openModal(data["html"]);
document.querySelector("#redirect").value = window.location.href;
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");
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";
});
});
});
});
-118
View File
@@ -1,118 +0,0 @@
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";
}
});
+47
View File
@@ -0,0 +1,47 @@
let dropdowns = document.querySelectorAll(".dropdown");
dropdowns.forEach((el) => {
el.addEventListener("click", (e) => {
e.stopPropagation();
let dropContent = el.querySelector(".dropdownContent");
dropContent.style.display = "block";
dropContent.addEventListener("click", (e) => {
e.stopPropagation();
});
});
});
window.addEventListener("click", () => {
document.querySelectorAll(".dropdownContent").forEach((dc) => {
dc.style.display = "none";
});
});
function deleteSpace(id) {
document.querySelector("#space-" + id).remove();
fetch("director.php", {
method: "POST",
// TODO: Add Authorization header with JWT
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: "ajaxId=deleteSpace&id=" + id,
});
}
function deletePost(id) {
document.querySelector("#post-" + id).remove();
fetch("director.php", {
method: "POST",
// TODO: Add Authorization header with JWT
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: "ajaxId=deletePost&id=" + id,
});
}
-93
View File
@@ -1,93 +0,0 @@
const login = document.querySelector("#login");
const logout = document.querySelector("#logout");
const stdModal = document.querySelector("#stdModal");
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(() => {
window.location.href = "spaces.php?view=list";
});
} else {
window.location.href = "spaces.php?view=list";
}
});
});
}
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"];
}
});
}
});
}
+31 -12
View File
@@ -1,16 +1,35 @@
const nav = document.querySelector('nav');
const nav_links = nav.querySelectorAll('ul li a');
const theme_toggle = nav.querySelector('button');
const nav = document.querySelector("nav");
const nav_links = nav.querySelectorAll("ul li a");
const theme_toggle = nav.querySelector("button");
const back = document.querySelector("#backButton");
const links = document.querySelectorAll(".fillDiv");
nav_links.forEach((el) => {
el.addEventListener('click', () => {
if (back)
back.addEventListener("click", () => {
console.log("back");
history.back();
});
links.forEach((el) => {
el.addEventListener("click", () => {
el.preventDefault();
if ('startViewTransition' in document) {
document.startViewTransition(() => {
window.location.href = el.getAttribute('href');
});
} else {
window.location.href = el.getAttribute('href');
}
applyTransition(el.getAttribute("href"));
});
});
nav_links.forEach((el) => {
el.addEventListener("click", () => {
el.preventDefault();
applyTransition(el.getAttribute("href"));
});
});
function applyTransition(href) {
if ("startViewTransition" in document) {
document.startViewTransition(() => {
window.location.href = href;
});
} else {
window.location.href = href;
}
}
View File
View File
View File
+34
View File
@@ -0,0 +1,34 @@
const darkThemeMq = window.matchMedia("(prefers-color-scheme: dark)");
if (darkThemeMq.matches) {
const link = document.createElement("link");
link.rel = "stylesheet";
link.type = "text/css";
link.href = "css/dark.css";
document.head.appendChild(link);
// Theme set to dark.
} else {
const link = document.createElement("link");
link.rel = "stylesheet";
link.type = "text/css";
link.href = "css/light.css";
document.head.appendChild(link);
// Theme set to light.
}
darkThemeMq.addEventListener("change", (e) => {
if (e.matches) {
const link = document.createElement("link");
link.rel = "stylesheet";
link.type = "text/css";
link.href = "css/dark.css";
document.head.appendChild(link);
// Theme set to dark.
} else {
const link = document.createElement("link");
link.rel = "stylesheet";
link.type = "text/css";
link.href = "css/light.css";
document.head.appendChild(link);
// Theme set to light.
}
});
+245
View File
@@ -0,0 +1,245 @@
const login = document.querySelector("#login");
const logout = document.querySelector("#logout");
const signup = document.querySelector("#signup");
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(() => {
window.location.href = "spaces.php?view=list";
});
} else {
window.location.href = "spaces.php?view=list";
}
});
});
}
if (login) {
login.addEventListener("click", () => {
console.log("click");
fetch("director.php", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: "ajaxId=loginHTML",
})
.then((response) => {
return response.json();
})
.then((data) => {
openModal(data["html"]);
const username_field = modalContent.querySelector("#username");
const passwordField = modalContent.querySelector("#password");
const submit_button = modalContent.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) => {
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"];
}
});
}
});
});
}
if (signup) {
signup.addEventListener("click", () => {
fetch("director.php", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: "ajaxId=signupHTML",
})
.then((response) => {
return response.json();
})
.then((data) => {
openModal(data["html"]);
const submit = modalContent.querySelector('input[type="submit"]');
submit.disabled = true;
const signupErrorArea = modalContent.querySelector("#signupError");
const usernameField = modalContent.querySelector("#username");
usernameField.addEventListener("blur", checkUsername);
const passwordField = modalContent.querySelector("#password");
passwordField.addEventListener("input", checkPW);
const vPasswordField = modalContent.querySelector("#vPassword");
vPasswordField.addEventListener("input", matchPW);
submit.addEventListener("click", (e) => {
e.preventDefault();
checkUsername();
checkPW();
matchPW();
if (
usernameField.value != "" &&
passwordField.value != "" &&
vPasswordField.value != "" &&
signupErrorArea.innerHTML == ""
)
modalContent.querySelector("form").submit();
});
function checkUsername() {
const username = usernameField.value;
fetch("director.php", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: "ajaxId=usernameCheck&username=" + username,
})
.then((response) => {
if (!response.ok) {
console.log("Failed to check if username exists!");
}
return response.json(); // Parse response body as JSON
})
.then((data) => {
if (data["exists"]) {
console.log("user exists");
if (!document.querySelector("#userExists")) {
let p = document.createElement("p");
p.id = "userExists";
p.innerText = "Username is taken.";
signupErrorArea.append(p);
submit.disabled = true;
}
} else {
let p = signupErrorArea.querySelector("#userExists");
if (p) p.remove();
matchPW();
if (
signupErrorArea.innerHTML == "" &&
passwordField.value != "" &&
vPasswordField.value != ""
)
submit.disabled = false;
}
});
}
function checkPW() {
let pw = passwordField.value;
if (pw.length < 8) {
if (!document.querySelector("#pwLength")) {
let p = document.createElement("p");
p.id = "pwLength";
p.innerText =
"Password length must be greater than 8 characters.";
signupErrorArea.append(p);
}
} else {
let p = signupErrorArea.querySelector("#pwLength");
if (p) p.remove();
matchPW();
if (
signupErrorArea.innerHTML == "" &&
passwordField.value != "" &&
vPasswordField.value != ""
)
submit.disabled = false;
}
const num_regex = /\d/;
if (!num_regex.test(pw)) {
if (!document.querySelector("#pwNum")) {
let p = document.createElement("p");
p.id = "pwNum";
p.innerText = "Password must have at least 1 digit.";
signupErrorArea.append(p);
submit.disabled = true;
}
} else {
let p = signupErrorArea.querySelector("#pwNum");
if (p) p.remove();
matchPW();
if (
signupErrorArea.innerHTML == "" &&
passwordField.value != "" &&
vPasswordField.value != ""
)
submit.disabled = false;
}
}
function matchPW() {
let pw = passwordField.value;
let vPW = vPasswordField.value;
if (pw != vPW) {
if (!document.querySelector("#pwMatch")) {
let p = document.createElement("p");
p.id = "pwMatch";
p.innerText = "Passwords must match.";
signupErrorArea.append(p);
submit.disabled = true;
}
} else {
let p = signupErrorArea.querySelector("#pwMatch");
if (p) p.remove();
if (
signupErrorArea.innerHTML == "" &&
passwordField.value != "" &&
vPasswordField.value != ""
)
submit.disabled = false;
}
}
});
});
}
+21
View File
@@ -0,0 +1,21 @@
const stdModal = document.querySelector("#stdModal");
let modalContent = document.querySelector(".modalContent");
function openModal(html) {
stdModal.innerHTML = html;
stdModal.style.display = "flex";
modalContent = document.querySelector(".modalContent");
window.addEventListener("click", () => {
closeModal();
});
modalContent.addEventListener("click", (e) => {
e.stopPropagation();
});
}
function closeModal() {
stdModal.innerHTML = "";
stdModal.style.display = "none";
}