version 1.0.0 commit

This commit is contained in:
Soulful Sailer
2026-03-04 21:00:14 -06:00
parent 13061a389f
commit eb0916d90a
17 changed files with 1941 additions and 0 deletions

153
static/scripts/EventItem.js Normal file
View File

@@ -0,0 +1,153 @@
class EventItem {
constructor(eventObject) {
this.id = eventObject["id"];
this.name = eventObject["name"];
this.startTime = new Date(Date.parse(eventObject["starttime"]));
this.endTime = new Date(Date.parse(eventObject["endtime"]));
this.people = eventObject["people"];
this.desc = eventObject["description"];
this.constructElem();
}
editEvent() {
window.location.replace(`./event.html?id=${this.id}`);
}
/**
* Creates the HTML Element for this Event using the standard format
*
* <div id='event-#' class='event'>
* <span class='event-topLine'>
* <h3>Example Event</h3>
* <span class='event-buttons'>
* <button class='event-edit'>Edit</button>
* </span>
* </span>
* <this.sameDayElem() or this.bothDaysElem()>
* <li class='event-people'>People Involved</li>
* <li class='event-desc'>Description</li>
* </div>
*/
constructElem() {
this.elem = document.createElement("div");
this.elem.id = `event-${this.id}`;
this.elem.classList.add("event");
//top line includes event name and button section
let topLine = document.createElement("span");
topLine.classList.add("event-topLine");
//event name
let title = document.createElement("h3");
title.innerText = this.name;
topLine.append(title);
//button section as edit button
let buttons = document.createElement("span");
buttons.classList.add("event-buttons");
//edit button
let editButton = document.createElement("button");
editButton.classList.add("event-edit");
editButton.innerText = "Edit";
buttons.append(editButton);
topLine.append(buttons);
this.elem.append(topLine);
//topLine end
//datetime includes event date and time
//if start and end time are less than 24h apart, only show the day for the start time
if ((this.endTime.getTime() - this.startTime.getTime()) / 3600000 < 24)
this.elem.append(this.sameDayElem());
else
this.elem.append(this.bothDaysElem());
//people involved in event
let eventPeople = document.createElement("li");
eventPeople.classList.add("event-people");
eventPeople.innerText = this.people;
this.elem.append(eventPeople);
//description of event
let eventDesc = document.createElement("li");
eventDesc.classList.add("event-desc");
eventDesc.innerText = this.desc;
this.elem.append(eventDesc);
//elem end
editButton.addEventListener("click", () => this.editEvent());
}
/**
* Creates the HTML Element for datetime section of the Event using the standard format
* When only the day is shown for the start time
*
* <li class='event-datetime'>
* DayOfWeek, Month ##<br/>
* <time datetime='YYYY-MM-DD HH:MM'>HH:MM AM/PM</time> - <time datetime='YYYY-MM-DD HH:MM'>HH:MM AM/PM</time>
* </li>
*
* @returns {HTMLElement} datetime - li that contains start date and time info
*/
sameDayElem() {
let datetime = document.createElement("li");
datetime.classList.add = "event-datetime";
//Day for starting time
datetime.append(getDay(this.startTime));
//linebreak
datetime.append(document.createElement('br'));
//starting time within HTML timestamp
let start = document.createElement("TIME");
start.setAttribute("datetime", this.startTime.toISOString().slice(0, 16).replace('T', ' '));
start.innerText = getTime(this.startTime);
datetime.append(start);
//seperator
datetime.append(" - ");
//ending time within HTML timestamp
let end = document.createElement("TIME");
end.setAttribute("datetime", this.endTime.toISOString().slice(0, 16).replace('T', ' '));
end.innerText = getTime(this.endTime);
datetime.append(end);
return datetime;
}
/**
* Creates the HTML Element for datetime section of the Event using the standard format
* When the day is shown for both start and end times
*
* <li class='event-datetime'>
* <time datetime='2023-04-28 21:30'>Friday, April 28 9:30 PM</time><br/>
* <time datetime='2023-04-29 22:30'>Saturday, April 28 10:30 PM</time>
* </li>
*
* @returns {HTMLElement} datetime - li that contains end date and time info
*/
bothDaysElem() {
let datetime = document.createElement("li");
datetime.classList.add("event-datetime");
//starting day and time within HTML timestamp
let start = document.createElement("TIME");
start.setAttribute("datetime", this.startTime.toISOString().slice(0, 16).replace('T', ' '));
start.innerText = `${getDay(this.startTime)} ${getTime(this.startTime)}`;
datetime.append(start);
//linebreak
datetime.append(document.createElement('br'));
//ending day and time within HTML timestamp
let end = document.createElement("TIME");
end.setAttribute("datetime", this.endTime.toISOString().slice(0, 16).replace('T', ' '));
end.innerText = `${getDay(this.endTime)} ${getTime(this.endTime)}`;
datetime.append(end);
return datetime;
}
}

110
static/scripts/editEvent.js Normal file
View File

@@ -0,0 +1,110 @@
let newEvent = true; //false if editing exisiting event
let currentURL = new URL(window.location.href);
let id = currentURL.searchParams.get("id"); //id of event being edited
/** load event data **/
/**
* Checks if we are editing event, and sets up page for it if so
*/
function editEvent() {
if (id) {
fetchEventData(id, populateData);
newEvent = false;
indicateEditing();
}
}
/**
* requests data from server about an event with specified id
* @param {number} id - id of event
* @param {function} callback
* @returns {Object} eventData - data about requested event
*/
function fetchEventData(id, callback) {
fetchFile("event.json", "json", undefined, { "id": id }).then((eventData) => {
//If server replies with requested data, return it. Else, alert user
if (eventData) {
callback(eventData);
}
else {
alert("Could not retrieve event data");
window.location.replace("./index.html");
}
});
}
/**
* populates data about the event into the form's fields
* @param {Object} eventData - data about requested event
*/
function populateData(eventData) {
document.getElementById("event-id").value = id;
for (let item in eventData) {
//the key for each item should equal the id of the field
let itemElem = document.getElementById(item);
if (itemElem) {
//map data to expected value for that field type
switch (itemElem.type) {
case "datetime-local":
let datetime = new Date(Date.parse(eventData[item]));
datetime = datetime.toISOString().slice(0, 16);
itemElem.defaultValue = datetime;
break;
default:
itemElem.defaultValue = eventData[item];
}
}
else console.log("Could not find field " + item);
}
//set section radio button in included
if (eventData["section"]) document.getElementById(eventData["section"]).checked = true;
}
/**
* Adds an item on the navigation bar to show the user is editing an event instead of adding one
*/
function indicateEditing() {
document.querySelector(".current-page").classList.remove('current-page');
//creates html element:
//<li class='current-page'><a href='event.html?id=EventID'><span class='link'>Editing</span></a></li>
let elem = document.createElement("li");
elem.classList.add('current-page');
let a = document.createElement('a');
a.href = window.location.href;
let span = document.createElement('span');
span.classList.add('link');
span.append('Editing');
a.append(span);
elem.append(a);
document.getElementById("links").append(elem); //add elem to navigation bar
//creates delete button
//<button id="delete-button">Delete</button>
let deleteButton = document.createElement("button");
deleteButton.id = "delete-button";
deleteButton.innerText = "Delete";
deleteButton.addEventListener("click", deleteEvent);
document.getElementById("body-container").append(deleteButton);
}
/**
* Sents post request to delete current event
*/
function deleteEvent() {
console.log(id);
if (confirm("Delete this event?")) {
postData("delete-event.json",
JSON.stringify({"id":id}),
"application/json")
.then(res => {
if (!res || !res.ok) alert("delete failed");
else window.location.replace("./index.html");
});
}
}
document.addEventListener("DOMContentLoaded", editEvent);

View File

@@ -0,0 +1,73 @@
let eventServer = new URL("http://" + window.location.host);
/**
* sends the specified GET request to the server and returns the response
* @param {string} filePath - path to requested file on server
* @param {string} dataType - type of data requested (text, json, blob)
* @param {Object} [headers] - request headers if needed
* @param {Object} [parameters] - Search Parameters
* @returns {Response} response - data returned by the server, decoded as indended
*/
function fetchFile(filePath, dataType, headers={}, parameters={}) {
//setup URL
let fileURL = eventServer;
fileURL.pathname = `/${filePath}`;
for (p in parameters) fileURL.searchParams.append(p, parameters[p]);
headers["method"] = "GET";
return fetch(fileURL, headers)
.then(response => {
//If server replies with requested file, return it. Else log HTTP error
if (response.ok) {
//decode the response as indended
switch (dataType) {
case "text": return response.text().then(data => { return data }); break;
case "json": return response.json().then(data => { return data }); break;
case "blob": return response.blob().then(data => { return data }); break;
}
}
else {
console.log(`HTTP-Error: ${events.status}\n${fileURL}`);
return undefined;
}
})
//if request is unable to be sent, log error
.catch(error => {
console.log(error.message);
return undefined;
});
}
/**
* sends specified data as a POST request to the server
* @param {string} filePath - path to requested file on server
* @param {string} data - stringified data to be sent to server
* @param {string} contentType - content type header for POST request
* @param {Object} [headers] - request headers if needed
* @returns {Response} response - server's response to the request
*/
function postData(filePath, data, contentType, headers={}) {
//setup URL
let fileURL = eventServer;
fileURL.pathname = `/${filePath}`;
headers["method"] = "POST";
headers["headers"] = {"Content-Type" : contentType};
headers["body"] = data;
return fetch(fileURL, headers)
.then(response => {
//return the server's response, log if there is an HTTP error
if (response.ok)
return response;
else {
console.log(`HTTP-Error: ${response.status}\n${fileURL}`);
return response;
}
})
//if request is unable to be sent, log error
.catch(error => {
console.log(error.message);
return undefined;
});
}

View File

@@ -0,0 +1,98 @@
/**
* returns string of Date object in format: HH:MM AM/PM
* @param {Date} time
* @returns {string} time - HH:MM AM/PM
*/
function getTime(time) {
let hours = time.getHours();
let meridiem;
if (hours > 12) {
hours -= 12;
meridiem = "PM";
}
else {
meridiem = "AM";
}
return `${hours}:${time.getMinutes()} ${meridiem}`;
}
/**
* returns string of Date object in format: DayOfWeek, Month DD
* @param {Date} time
* @returns {string} date - DayOfWeek, Month DD
*/
function getDay(time) {
let day;
switch(time.getDay()) {
case 0:
day = 'Sunday';
break;
case 1:
day = 'Monday';
break;
case 2:
day = 'Tuesday';
break;
case 3:
day = 'Wednesday';
break;
case 4:
day = 'Thursday';
break;
case 5:
day = 'Friday';
break;
case 6:
day = 'Saturday';
break;
default:
day = 'Invalid';
}
day = day + ', ';
switch(time.getMonth()) {
case 0:
day = day + "January";
break;
case 1:
day = day + "February";
break;
case 2:
day = day + "March";
break;
case 3:
day = day + "April";
break;
case 4:
day = day + "May";
break;
case 5:
day = day + "June";
break;
case 6:
day = day + "July";
break;
case 7:
day = day + "August";
break;
case 8:
day = day + "September";
break;
case 9:
day = day + "October";
break;
case 10:
day = day + "November";
break;
case 11:
day = day + "December";
break;
default:
day = day + "Invalid";
}
day = day + " " + time.getDate();
return day;
}

View File

@@ -0,0 +1,29 @@
/**
* Retrieves the list of events from the server and adds them respective to their section
*/
function loadEvents() {
fetchFile("events.json", "json").then((events) => {
//if server replies with requested data
if (events) {
for (let header in events) {
events[header].forEach((eventData) => {
addEvent(eventData, header);
});
}
}
else console.log("Could not retrieve event data");
});
}
/**
* Adds event to specified header via creating a new instance of EventItem
* @param {Object} eventData - contains required information about the event
* @param {string} header - specifies under which section to add the new event item
*/
function addEvent(eventData, header) {
let item = new EventItem(eventData);
document.getElementById(header).append(item.elem);
}
document.addEventListener("DOMContentLoaded", loadEvents);